package com.elvish.oda.common.conf.shiro;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.elvish.oda.busin.pojo.Permission;
import com.elvish.oda.busin.pojo.User;
import com.elvish.oda.busin.service.UserService;
import com.elvish.oda.common.utils.Md5Util;

/**
 * 
 * @author SPPan
 *
 */
@Component
public class MyRealm extends AuthorizingRealm {

	public MyRealm() {
		super(new AllowAllCredentialsMatcher());
		setAuthenticationTokenClass(UsernamePasswordToken.class);
	}

	@Autowired
	private UserService userService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		List<Permission> infos = userService.findMyPermitions();
		Set<String> permissions = new HashSet<String>();
		Set<String> roles = new HashSet<String>();
		if (infos != null && infos.size() > 0) {
			for (Permission info : infos) {
				permissions.add(info.getPermissionCode());
				roles.add(info.getRoleId());
			}
		}
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setStringPermissions(permissions);
		authorizationInfo.setRoles(roles);
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();
		User user = userService.findByUsername(username);
		if (user == null) {// 账号不存在
			throw new UnknownAccountException("账号不存在！");
		}
		// 账号锁定
		if (user.getDelflag() == 1) {
			throw new LockedAccountException("账号已被锁定,请联系管理员！");
		}
		// 验证密码
		String password = new String((char[]) token.getCredentials());
		if (!Md5Util.md5(password).equals(user.getPassword())) {
			throw new IncorrectCredentialsException("密码不正确！");
		}

		// 更新登录时间
		user.setLoginTime(new Date());
		userService.updateUserSelective(user, "^loginTime$");

		return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
	}

}
